package com.fick.hibernate.dao;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;

import com.fick.hibernate.HibernateSessionFactory;

/**
 * Data access object (DAO) for domain model
 * 
 * @author MyEclipse Persistence Tools
 */
public class BaseHibernateDAO implements IBaseHibernateDAO {
	private static final Log log = LogFactory.getLog(BaseHibernateDAO.class);

	public void closeSession() {
		HibernateSessionFactory.closeSession();
	}

	public Integer count(Class clazz, String sql) {
		int count = 0;
		try {
			count = (Integer) this.getSession().createQuery("select count(*) from " + clazz.getName() + " " + sql)
					.uniqueResult();
		} catch (Exception e) {
		} finally {
			closeSession();
		}
		return count;
	}

	public boolean delAll(Object obj) {
		log.debug("delete all object");
		try {
			Transaction ts = getSession().beginTransaction();
			getSession().createQuery("delete from " + obj.getClass().getName());
			ts.commit();
		} catch (RuntimeException re) {
			log.error("delAll false", re);
			throw re;
		} finally {
			closeSession();
		}
		return true;
	}

	public boolean delByHql(String hql) {
		log.debug("delete object by hql" + hql);
		try {
			Transaction ts = getSession().beginTransaction();
			Query query = getSession().createQuery(hql);
			query.executeUpdate();
			ts.commit();
		} catch (RuntimeException re) {
			log.error("delete by hql false", re);
			throw re;
		} finally {
			closeSession();
		}
		return true;
	}

	public boolean delete(Object obj) {
		log.debug("delete object " + obj.getClass().getName());
		try {
			Transaction ts = getSession().beginTransaction();
			getSession().delete(obj);
			ts.commit();
		} catch (RuntimeException re) {
			log.error("delete failed", re);
			throw re;
		} finally {
			closeSession();
		}
		return true;
	}

	public List findBySql(Class clazz, String sql) {
		log.debug("finding " + clazz + " instance with property");
		try {
			String queryString = "from " + clazz.getName() + " " + sql;
			Query queryObject = getSession().createQuery(queryString);
			return queryObject.list();
		} catch (RuntimeException re) {
			log.error("find by property name failed", re);
			throw re;
		}
	}

	public List findBySql(String sql) {
		log.debug("finding some page instance");
		try {
			Query query = getSession().createSQLQuery(sql);
			log.debug("find  some page instance successful");
			return query.list();
		} catch (RuntimeException re) {
			log.error("find by example failed", re);
			throw re;
		}
	}

	public List findBySql(String sql, int currPage, int pageSize) {
		log.debug("finding some page instance");
		try {
			Query query = getSession().createSQLQuery(sql);
			query.setFirstResult((currPage - 1) * pageSize);
			query.setMaxResults(pageSize);
			log.debug("find  some page instance successful");
			return query.list();
		} catch (RuntimeException re) {
			log.error("find by example failed", re);
			throw re;
		}
	}

	public List findPageBySql(Class clazz, int currPage, int pageSize, String sql) {
		log.debug("finding some page instance");
		try {
			Query query = getSession().createQuery("from " + clazz.getName() + " " + sql); // 100
			query.setFirstResult((currPage - 1) * pageSize); // 从哪开始
			query.setMaxResults(pageSize); // 到哪结束
			log.debug("find  some page instance successful");
			return query.list();
		} catch (RuntimeException re) {
			log.error("find by example failed", re);
			throw re;
		}
	}

	@Override
	public Session getSession() {
		return HibernateSessionFactory.getSession();
	}

	public Integer getTotalCount(Class clazz) {
		int count = 0;
		try {
			count = (Integer) this.getSession().createQuery("select count(*) from " + clazz.getName()).uniqueResult();
		} catch (Exception e) {
		} finally {
			closeSession();
		}
		return count;
	}

	public void save(Object obj) {
		log.debug("saving object" + obj.getClass().getName());
		try {
			Transaction ts = getSession().beginTransaction();
			getSession().save(obj);
			ts.commit();
			log.debug("save successful");
		} catch (RuntimeException re) {
			log.error("save failed", re);
			throw re;
		} finally {
			closeSession();
		}
	}

	public void saveOrUpdate(Object obj) {
		log.debug("saving or updating object" + obj.getClass().getName());
		try {
			Transaction ts = getSession().beginTransaction();
			getSession().saveOrUpdate(obj);
			ts.commit();
			log.debug("save successful");
		} catch (RuntimeException re) {
			log.error("save failed", re);
			throw re;
		} finally {
			closeSession();
		}
	}

	public boolean update(Object obj) {
		log.debug("update object" + obj.getClass().getName());
		try {
			Transaction ts = getSession().beginTransaction();
			getSession().update(obj);
			ts.commit();
		} catch (RuntimeException re) {
			log.error("update false", re);
			throw re;
		} finally {
			closeSession();
		}
		return true;
	}
}